import axios from 'axios'
import { local } from '@/utils/storage'
import { useAppsStore } from '@/stores/modules/app'
import { createDiscreteApi } from 'naive-ui'
import router from '@/router'
import qs from 'qs'

// axios.defaults.baseURL = import.meta.env.VITE_BASEURL
axios.defaults.baseURL = '/api/index'
axios.defaults.timeout = import.meta.env.VITE_REQUESTTIMEOUT
axios.defaults.headers.post['Content-Type'] = import.meta.env.VITE_CONTENT_TYPE
axios.defaults.headers.put['Content-Type'] = import.meta.env.VITE_CONTENT_TYPE

axios.interceptors.request.use(
  (config): any => {
    if (config?.url) {
      const token = local.get(import.meta.env.VITE_TOKEN_LOCATION_NAME)
      if (token) {
        config.headers[import.meta.env.VITE_TOKEN_NAME] = token
      }
    }
    return config
  },
  error => {
    return Promise.resolve(error)
  }
)
// 响应拦截
axios.interceptors.response.use(
  res => {
    if (res.config?.url && res.config.url.includes('http')) {
      return res
    } else if (res.data.code === 401) {
      const useApp = useAppsStore()
      const { signOut } = useApp
      signOut()
      router.replace('/login')
    }
    return res
  },
  error => {
    const { message } = createDiscreteApi(['message'])
    message.error(error.response.data.msg)
    return error
  }
)

interface ResType<T> {
  code: number
  data?: T
  message: string
  err?: string
}

interface Http {
  get<T>(url: string, params?: unknown): Promise<ResType<T>>
  post<T>(url: string, params?: unknown, config?: any): Promise<ResType<T>>
  put<T>(url: string, params?: unknown, config?: any): Promise<ResType<T>>
  delete<T>(url: string, params?: unknown, headers?: any): Promise<ResType<T>>
  upload<T>(
    url: string,
    params: unknown,
    onUploadProgress?: any
  ): Promise<ResType<T>>
  download(url: string): void
}

const http: Http = {
  get(url, params) {
    return new Promise((resolve, reject) => {
      axios
        .get(url, {
          params,
          paramsSerializer: function (params) {
            return qs.stringify(params, { arrayFormat: 'repeat' })
          }
        })
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },

  post(url, params, config = null) {
    return new Promise((resolve, reject) => {
      axios
        .post(url, JSON.stringify(params), config)
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },
  put(url, params, config = null) {
    return new Promise((resolve, reject) => {
      axios
        .put(url, JSON.stringify(params), config)
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },
  delete(url, data, headers) {
    return new Promise((resolve, reject) => {
      axios
        .delete(url, {
          data,
          headers
        })
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },

  upload(url: string, file, onUploadProgress?: any) {
    const configOptions: any = {
      headers: { 'Content-Type': 'multipart/form-data' }
    }
    if (onUploadProgress) {
      configOptions.onUploadProgress = onUploadProgress
    }
    return new Promise((resolve, reject) => {
      axios
        .post(url, file, configOptions)
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },

  download(url: string): void {
    const iframe: HTMLIFrameElement = document.createElement('iframe')
    iframe.style.display = 'none'
    iframe.src = url
    iframe.onload = function (): void {
      document.body.removeChild(iframe)
    }
    document.body.appendChild(iframe)
  }
}

export default http
